/* Copyright (c) 2009-2010, Sean A.O. Harney <sharney3@gmail.com> */

#include "omf.h"


void *checked_malloc(size_t size)
{
/*    return checked_calloc(1, size); // malloc differs from calloc in that calloc zeros the mem */
    void *ret = malloc(size);
    if (ret == NULL)
	fatal_error_perror("calloc()");

    return ret;
}

void *checked_calloc(size_t nmemb, size_t size)
{
    void *ret = calloc(nmemb, size);
    if (ret == NULL)
	fatal_error_perror("calloc()");

    return ret;
}

char *checked_strdup(const char *s)
{
    char *ret;

    if (s == NULL)
	fatal_error_println("checked_strdup(NULL)");

    ret = strdup(s);
    if (ret == NULL)
	fatal_error_perror("strdup()");

    return ret;

}

void fatal_error()
{
    fatal_error_println("Error, exiting.");
}

//uses errno like perror
void fatal_error_perror(const char *s)
{
    fatal_error_strerror(s, errno);
}

void fatal_error_strerror(const char *s, int errnum)
{
    fatal_error_println("%s : %s", s, strerror(errnum));
}

//adds the \n
void fatal_error_println(const char *fmt, ...)
{
    va_list argp;
    char fixed_fmt[1024];

    snprintf(fixed_fmt, sizeof(fixed_fmt), "Error, exiting. Error: %s\n",
	     fmt);

    va_start(argp, fmt);	//fmt is last before the elipsis ...
    vfprintf(stderr, fixed_fmt, argp);
    va_end(argp);

    fflush(stderr);
    exit(EXIT_FAILURE);		/* the fatal part */
}


void error_print(const char *fmt, ...)
{
    va_list argp;

    va_start(argp, fmt);	//fmt is last before the elipsis ...
    vfprintf(stderr, fmt, argp);
    va_end(argp);
    fflush(stderr);
}

void error_println(const char *fmt, ...)
{
    va_list argp;

    va_start(argp, fmt);	//fmt is last before the elipsis ...
    vfprintf(stderr, fmt, argp);
    va_end(argp);

    fprintf(stderr, "\n");
    fflush(stderr);
}

bool fd_lock(int fd)
{
    if (flock(fd, LOCK_EX) < 0)
      {
	  perror("fd_lock()");
	  return false;
      }
    return true;
}

bool fd_unlock(int fd)
{
    if (flock(fd, LOCK_UN) < 0)
      {
	  perror("fd_unlock()");
	  return false;
      }
    return true;
}

bool fp_lock(FILE * fp)
{
    int fd = fileno(fp);	// if fp is invalid, will return -1 and errno=EBADF

    if (fd < 0)
	return false;
    return fd_lock(fd);
}

bool fp_unlock(FILE * fp)
{
    int fd = fileno(fp);	// if fp is invalid, will return -1 and errno=EBADF

    if (fd < 0)
	return false;
    return fd_unlock(fd);
}


bool get_omf_running_time(struct timeval * ret)
{
    struct timeval curtime;
    if (gettimeofday(&curtime, NULL) < 0)
      {
	  perror("gettimeofday()");
	  return false;
      }

    timeval_subtract(ret, &curtime, &(glob.omf_starttime));
    return true;
}
